package com.pitop.base.interceptor;

import com.auth0.jwt.JWTCreator;
import com.opensso.sdk.tools.SessionTools;
import com.pitop.core.enums.SessionEnum;
import com.pitop.core.exceptions.BaseException;
import com.pitop.core.tools.JwtToken;
import com.pitop.core.tools.redis.RedisUtils;
import com.pitop.setting.entity.Setting;
import com.pitop.setting.service.SettingSVImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * LoginInterceptor
 * * 在未使用open-sso时，使用该拦截器；使用open-sso时，使用LoginInterceptor_bak拦截器
 */
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    @Resource
    private RedisUtils redisUtils;
    @Resource
    private SettingSVImpl settingSVImpl;//设置

    /**
     * 登录拦截器，拦截token的合法性
     * 1.拦截到Authorization
     * 2.解密并计算sessionkey
     * 3.判断本地sessionkey是否存在
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1.拦截到Authorization
        String token = request.getHeader(SessionEnum.authorization.name());

        if (StringUtils.isBlank(token)) {
            return false;
        }
        //2.解密并计算sessionkey
        String sso_secret = settingSVImpl.loadByK(Setting.Key.Token_Secret.name()).getV();
        String account = JwtToken.getTokenValue(token, sso_secret, SessionEnum.Account.name());
        String sessionKey = SessionTools.Instance.genSessionKey(account);
        //3.判断本地sessionkey是否存在
        if (!redisUtils.hasKey(sessionKey)) {
            throw new BaseException(BaseException.BaseExceptionEnum.Session_Error);
        }

        String session_expire_timeStr = JwtToken.getTokenValue(token, sso_secret, SessionEnum.Session_Expire_Time.name());
        if (session_expire_timeStr == null) {
            throw new BaseException(BaseException.BaseExceptionEnum.Session_Error);
        }
        int session_expire_time = Integer.parseInt(session_expire_timeStr);

        JWTCreator.Builder builder = JwtToken.create();
        builder.withClaim(SessionEnum.SessionKey.name(), sessionKey)
                .withClaim(SessionEnum.Code.name(), JwtToken.getTokenValue(token, sso_secret, SessionEnum.Code.name()))
                .withClaim(SessionEnum.Session.name(), JwtToken.getTokenValue(token, sso_secret, SessionEnum.Session.name()))
                .withClaim(SessionEnum.Account.name(), account)
                .withClaim(SessionEnum.Session_Expire_Time.name(), String.valueOf(session_expire_time));
        token = JwtToken.createToken(builder, sso_secret, session_expire_time);

        redisUtils.expire(sessionKey, session_expire_time);//刷新局部会话过期时间
        response.addHeader(SessionEnum.authorization.name(), token);

        return true;

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}